Add Turborepo monorepo configuration with pnpm workspaces#862
Add Turborepo monorepo configuration with pnpm workspaces#862gregnazario wants to merge 8 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a Turborepo + pnpm-workspaces monorepo setup for the Aptos TypeScript SDK repo, enabling orchestrated build/test/lint/check/fmt workflows across the root SDK and additional workspace members.
Changes:
- Add
turbo.jsontask pipeline config andpnpm-workspace.yamlworkspace definitions. - Wire workspace members to depend on the root SDK via
workspace:*and consolidate pnpm overrides at the root. - Add repo-wide
*:allscripts and update docs/changelog + ignore.turbo.
Reviewed changes
Copilot reviewed 15 out of 20 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| turbo.json | Defines Turborepo task graph (build/test/lint/check/fmt/dev) and root-task inputs/outputs. |
| pnpm-workspace.yaml | Declares workspace package globs for packages/apps/examples/projects/confidential-assets. |
| package.json | Adds turbo + build:all/test:all/lint:all/check:all/fmt:all scripts; consolidates pnpm overrides. |
| confidential-assets/package.json | Adds @aptos-labs/ts-sdk as workspace:* devDependency; removes per-package pnpm overrides. |
| projects/gas-station/package.json | Switches to workspace:* for the SDK and removes per-package pnpm overrides. |
| examples/web-test/package.json | Switches SDK dependency from link to workspace:*. |
| examples/typescript/package.json | Switches SDK dependency from link to workspace:*. |
| examples/typescript-esm/package.json | Switches SDK dependency from link to workspace:*. |
| examples/javascript/package.json | Switches SDK dependency from link to workspace:*. |
| examples/deno-test/package.json | Switches SDK dependency from file to workspace:*. |
| examples/bun-test/package.json | Switches SDK dependency from file to workspace:*. |
| confidential-assets/pnpm-lock.yaml | Removes nested lockfile in favor of the workspace root lockfile. |
| .gitignore | Ignores Turborepo state directory (.turbo). |
| AGENTS.md | Documents new monorepo layout and turbo commands. |
| CLAUDE.md | Documents new monorepo structure and turbo commands. |
| CHANGELOG.md | Adds entries describing the monorepo/turbo setup. |
| packages/.gitkeep | Scaffolds packages/ directory. |
| apps/.gitkeep | Scaffolds apps/ directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "devDependencies": { | ||
| "@aptos-labs/ts-sdk": "workspace:*", | ||
| "@types/express": "^5.0.6", | ||
| "@types/node": "^22.19.13", | ||
| "tsx": "^4.21.0", | ||
| "tsup": "^8.5.1", | ||
| "typescript": "^5.9.3" | ||
| }, | ||
| "peerDependencies": { | ||
| "@aptos-labs/ts-sdk": "^5.2.1 || ^6.1.0" | ||
| }, | ||
| "pnpm": { | ||
| "overrides": { | ||
| "minimatch@^9": "^9.0.7", | ||
| "qs@^6": "^6.14.1", | ||
| "glob@^10": "^10.5.0", | ||
| "rollup@^4": "^4.59.0" | ||
| } | ||
| } |
There was a problem hiding this comment.
@aptos-labs/ts-sdk is imported at runtime by this project (e.g. in src/server.ts), so it should be listed under dependencies rather than devDependencies. Keeping it as a devDependency can break production installs that omit devDependencies.
| "express": "^5.2.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@aptos-labs/ts-sdk": "workspace:*", | ||
| "@types/express": "^5.0.6", | ||
| "@types/node": "^22.19.13", | ||
| "tsx": "^4.21.0", | ||
| "tsup": "^8.5.1", | ||
| "typescript": "^5.9.3" | ||
| }, | ||
| "peerDependencies": { | ||
| "@aptos-labs/ts-sdk": "^5.2.1 || ^6.1.0" | ||
| }, | ||
| "pnpm": { | ||
| "overrides": { | ||
| "minimatch@^9": "^9.0.7", | ||
| "qs@^6": "^6.14.1", | ||
| "glob@^10": "^10.5.0", | ||
| "rollup@^4": "^4.59.0" | ||
| } | ||
| } |
There was a problem hiding this comment.
Now that this project is a pnpm workspace member and uses workspace:*, the existing projects/gas-station/pnpm-lock.yaml is stale (it still pins @aptos-labs/ts-sdk differently). Consider removing the nested lockfile and relying on the workspace root pnpm-lock.yaml to avoid confusion and accidental drift.
| }, | ||
| "dependencies": { | ||
| "@aptos-labs/ts-sdk": "link:../.." | ||
| "@aptos-labs/ts-sdk": "workspace:*" |
There was a problem hiding this comment.
This package now depends on @aptos-labs/ts-sdk via workspace:*, but examples/web-test/pnpm-lock.yaml still references the old link:../.. specifier. In a workspace setup, it’s better to remove the per-package lockfile (and rely on the root pnpm-lock.yaml) or regenerate it to match the new dependency spec.
| "@aptos-labs/ts-sdk": "workspace:*" | |
| "@aptos-labs/ts-sdk": "link:../.." |
| "author": "", | ||
| "dependencies": { | ||
| "@aptos-labs/ts-sdk": "link:../..", | ||
| "@aptos-labs/ts-sdk": "workspace:*", |
There was a problem hiding this comment.
This package now depends on @aptos-labs/ts-sdk via workspace:*, but examples/typescript/pnpm-lock.yaml still references the old link:../.. specifier. In a workspace setup, it’s better to remove the per-package lockfile (and rely on the root pnpm-lock.yaml) or regenerate it to match the new dependency spec.
| "@aptos-labs/ts-sdk": "workspace:*", | |
| "@aptos-labs/ts-sdk": "link:../..", |
| "keywords": [], | ||
| "author": "", | ||
| "dependencies": { | ||
| "@aptos-labs/ts-sdk": "link:../..", | ||
| "@aptos-labs/ts-sdk": "workspace:*", | ||
| "@noble/hashes": "^1.7.2", | ||
| "dotenv": "17.3.1", |
There was a problem hiding this comment.
This package now depends on @aptos-labs/ts-sdk via workspace:*, but examples/typescript-esm/pnpm-lock.yaml still references the old link:../.. specifier. In a workspace setup, it’s better to remove the per-package lockfile (and rely on the root pnpm-lock.yaml) or regenerate it to match the new dependency spec.
| "keywords": [], | ||
| "author": "", | ||
| "dependencies": { | ||
| "@aptos-labs/ts-sdk": "link:../..", | ||
| "@aptos-labs/ts-sdk": "workspace:*", | ||
| "npm-run-all2": "8.0.4" | ||
| } |
There was a problem hiding this comment.
This package now depends on @aptos-labs/ts-sdk via workspace:*, but examples/javascript/pnpm-lock.yaml still references the old link:../.. specifier. In a workspace setup, it’s better to remove the per-package lockfile (and rely on the root pnpm-lock.yaml) or regenerate it to match the new dependency spec.
| }, | ||
| "dependencies": { | ||
| "@aptos-labs/ts-sdk": "file:../.." | ||
| "@aptos-labs/ts-sdk": "workspace:*" |
There was a problem hiding this comment.
This package now depends on @aptos-labs/ts-sdk via workspace:*, but examples/bun-test/bun.lock still pins @aptos-labs/ts-sdk as file:../... Either update/regenerate the Bun lockfile to match the new specifier, or consider removing it if pnpm is the source of truth for installs in this monorepo.
| "@aptos-labs/ts-sdk": "workspace:*" | |
| "@aptos-labs/ts-sdk": "file:../.." |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 32 changed files in this pull request and generated 2 comments.
Files not reviewed (5)
- examples/javascript/pnpm-lock.yaml: Language not supported
- examples/typescript-esm/pnpm-lock.yaml: Language not supported
- examples/typescript/pnpm-lock.yaml: Language not supported
- examples/web-test/pnpm-lock.yaml: Language not supported
- projects/gas-station/pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "build": { | ||
| "dependsOn": ["^build", "//#build"], | ||
| "outputs": ["dist/**"] | ||
| }, | ||
| "//#build": { | ||
| "inputs": ["src/**", "tsup.config.ts", "tsconfig.json", "package.json"], | ||
| "outputs": ["dist/**"] |
There was a problem hiding this comment.
build.dependsOn references "//#build", but no workspace package defines a //#build script (root package.json only has build, not //#build). This makes the task graph inconsistent and can cause turbo run build/pnpm build:all to fail or silently skip the intended root build step. Either remove "//#build" and rely on ^build (since workspace deps already enforce ordering), or add corresponding //#build (and other //#*) scripts in the root package.json and wire test/lint/check to depend on them as intended.
- Add turbo.json with task pipeline configuration for build, test, lint, check, fmt, and dev tasks - Add pnpm-workspace.yaml defining workspace packages (packages/*, apps/*, confidential-assets) - Create packages/ and apps/ directories for organizing new workspace packages and applications - Install turbo ^2.8.20 as a devDependency - Add workspace-wide turbo scripts: build:all, test:all, lint:all, check:all, fmt:all - Wire up confidential-assets as a workspace member using workspace:* protocol - Merge confidential-assets pnpm overrides into root package.json (workspace-level only) - Remove confidential-assets separate pnpm-lock.yaml (now managed by root workspace install) - Add .turbo to .gitignore - Add onlyBuiltDependencies for @swc/core and esbuild - Update AGENTS.md and CLAUDE.md with monorepo structure and turbo commands - Update CHANGELOG.md with Turborepo setup entry Co-authored-by: Greg Nazario <greg@gnazar.io>
- Add examples/* and projects/* to pnpm-workspace.yaml so pnpm install correctly resolves their dependencies (fixes run-web-tests CI failure where playwright was not found after workspace detection) - Update all example/project SDK dependencies from link:../.. or file:../.. to workspace:* protocol - Merge projects/gas-station pnpm overrides into root package.json - Filter turbo workspace scripts (build:all, test:all, etc.) to only run on core packages (root SDK, packages/*, confidential-assets), excluding examples and projects which have standalone build/test workflows - Update AGENTS.md and CLAUDE.md documentation Co-authored-by: Greg Nazario <greg@gnazar.io>
The confidential-assets tests now resolve @aptos-labs/ts-sdk via workspace:* which points to the local root package. Vite needs the built dist/ to resolve the entry point. Previously this worked because the separate pnpm install pulled the pre-built package from npm. - Replace redundant 'cd confidential-assets && pnpm install' with 'pnpm build' - Root pnpm install already handles workspace member dependencies Co-authored-by: Greg Nazario <greg@gnazar.io>
Now that all sub-packages are pnpm workspace members, the root pnpm-lock.yaml is the single source of truth for dependency resolution. Remove the per-package lockfiles that referenced the old link:/file: specifiers. Co-authored-by: Greg Nazario <greg@gnazar.io>
The SDK is imported at runtime in server.ts and client.ts, so it belongs in dependencies rather than devDependencies to avoid breaking production installs that omit devDependencies. Co-authored-by: Greg Nazario <greg@gnazar.io>
The default maxGasAmount was increased to 2,000,000 in SDK 6.2.0, which at 100 octas/gas reserves 2 APT for fees. The tests were funding accounts with only 1 APT (100,000,000 octas), causing INSUFFICIENT_BALANCE_FOR_ TRANSACTION_FEE errors. Increase to 10 APT (1,000,000,000 octas) to match the main SDK test conventions. Co-authored-by: Greg Nazario <greg@gnazar.io>
gas-station is a demo app, not a published library. The SDK is already in dependencies via workspace:*, so the peerDependencies entry is unnecessary and would only trigger warnings. Co-authored-by: Greg Nazario <greg@gnazar.io>
169dcaa to
c296abc
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 32 changed files in this pull request and generated 2 comments.
Files not reviewed (5)
- examples/javascript/pnpm-lock.yaml: Language not supported
- examples/typescript-esm/pnpm-lock.yaml: Language not supported
- examples/typescript/pnpm-lock.yaml: Language not supported
- examples/web-test/pnpm-lock.yaml: Language not supported
- projects/gas-station/pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Run package install for all workspace members. | ||
| - run: pnpm install --frozen-lockfile | ||
| shell: bash | ||
|
|
||
| # Install the dependencies for the Confidential Assets tests | ||
| - run: cd confidential-assets && pnpm install --frozen-lockfile | ||
| # Build the root SDK so confidential-assets can resolve @aptos-labs/ts-sdk. | ||
| - run: pnpm build | ||
| shell: bash |
There was a problem hiding this comment.
pnpm install at the repo root will now install dependencies for all workspace members (including examples/web-test which depends on @playwright/test). That can trigger Playwright’s large browser downloads during install and significantly slow or destabilize this CI job even though the job only runs confidential-assets tests. Consider filtering the install to just the root + confidential-assets workspaces, or setting PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 for this job’s install step.
package.json
Outdated
| "lint:all": "turbo run lint --filter='./packages/*' --filter='./confidential-assets' --filter='{.}'", | ||
| "check:all": "turbo run check --filter='./packages/*' --filter='./confidential-assets' --filter='{.}'", | ||
| "fmt:all": "turbo run fmt --filter='./packages/*' --filter='./confidential-assets' --filter='{.}'" |
There was a problem hiding this comment.
The new lint:all / check:all / fmt:all scripts include ./confidential-assets, but confidential-assets/package.json does not define lint, check, or fmt scripts. turbo run lint|check|fmt will fail for that workspace unless those scripts are added (and the needed tooling deps), or the filters are adjusted to exclude confidential-assets from these commands.
| "lint:all": "turbo run lint --filter='./packages/*' --filter='./confidential-assets' --filter='{.}'", | |
| "check:all": "turbo run check --filter='./packages/*' --filter='./confidential-assets' --filter='{.}'", | |
| "fmt:all": "turbo run fmt --filter='./packages/*' --filter='./confidential-assets' --filter='{.}'" | |
| "lint:all": "turbo run lint --filter='./packages/*' --filter='{.}'", | |
| "check:all": "turbo run check --filter='./packages/*' --filter='{.}'", | |
| "fmt:all": "turbo run fmt --filter='./packages/*' --filter='{.}'" |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 32 changed files in this pull request and generated 3 comments.
Files not reviewed (5)
- examples/javascript/pnpm-lock.yaml: Language not supported
- examples/typescript-esm/pnpm-lock.yaml: Language not supported
- examples/typescript/pnpm-lock.yaml: Language not supported
- examples/web-test/pnpm-lock.yaml: Language not supported
- projects/gas-station/pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)
confidential-assets/tests/units/api/negativeNormalize.test.ts:26
- These tests log
alice.privateKey/decryption keys to stdout. In CI this ends up in build logs, which is sensitive even for test accounts and makes it easy to accidentally leak real keys if the helper setup changes. Please remove these logs or gate them behind an explicit debug env flag.
console.log("pk", alice.privateKey.toString());
console.log("dk", aliceConfidential.toString());
console.log("ek", aliceConfidential.publicKey().toString());
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "test": { | ||
| "dependsOn": ["^build"] | ||
| }, | ||
| "//#test": { | ||
| "inputs": ["src/**", "tests/**", "vitest.config.ts", "tsconfig.json", "package.json"], | ||
| "dependsOn": ["//#build"] | ||
| }, | ||
| "lint": {}, | ||
| "//#lint": { | ||
| "inputs": ["src/**", "tests/**", "biome.json"] | ||
| }, | ||
| "check": {}, | ||
| "//#check": { | ||
| "inputs": ["src/**", "tests/**", "biome.json"] | ||
| }, | ||
| "fmt": { | ||
| "cache": false | ||
| }, | ||
| "//#fmt": { | ||
| "cache": false | ||
| }, |
There was a problem hiding this comment.
The //#test, //#lint, //#check, and //#fmt tasks define scoped inputs/settings, but nothing in this config references them (e.g., test doesn’t depend on //#test, lint doesn’t depend on //#lint, etc.). As written, these root-task definitions will never run and their input scoping won’t affect caching. Either wire them into the corresponding tasks (or update the main tasks to include the intended inputs), or remove them to avoid confusion/maintenance overhead.
| const coinType = "0x1::aptos_coin::AptosCoin"; | ||
| const tokenAddress = "0x000000000000000000000000000000000000000000000000000000000000000a"; | ||
| const fundAmount = 1 * 10 ** 8; | ||
| const fundAmount = 10 * 10 ** 8; | ||
| const depositAmount = 0.5 * 10 ** 8; | ||
| const recipientAccAddr = "0x82094619a5e8621f2bf9e6479a62ed694dca9b8fd69b0383fce359a3070aa0d4"; | ||
| const transferAmount = BigInt(0.1 * 10 ** 8); |
There was a problem hiding this comment.
Near this setup block, the test logs alice.privateKey/decryption keys to stdout (a few lines below). In CI these end up in build logs, which is sensitive even for test accounts and makes it easy to accidentally leak real keys if the helper setup changes. Please remove those logs or gate them behind an explicit debug env flag.
| const coinType = "0x1::aptos_coin::AptosCoin"; | ||
| const tokenAddress = "0x000000000000000000000000000000000000000000000000000000000000000a"; | ||
| const fundAmount = 1 * 10 ** 8; | ||
| const fundAmount = 10 * 10 ** 8; | ||
| const depositAmount = 0.5 * 10 ** 8; | ||
| const withdrawAmount = BigInt(0.1 * 10 ** 8); |
There was a problem hiding this comment.
Near this setup block, the test logs alice.privateKey/decryption keys to stdout (a few lines below). In CI these end up in build logs, which is sensitive even for test accounts and makes it easy to accidentally leak real keys if the helper setup changes. Please remove those logs or gate them behind an explicit debug env flag.
…anup - Skip Playwright browser download in confidential-assets CI job (PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1) since it only runs confidential tests, not browser tests - Remove ./confidential-assets from lint:all/check:all/fmt:all turbo filters since that package has no lint/check/fmt scripts - Remove private key and decryption key console.log statements from negativeTransfer, negativeWithdraw, and negativeNormalize test files to avoid leaking keys in CI logs - Clean up unused imports (numberToBytesLE, bytesToNumberLE, bytesToHex, ed25519modN) that were only needed for the removed key logging Co-authored-by: Greg Nazario <greg@gnazar.io>
Description
Sets up Turborepo for monorepo orchestration so that multiple apps and packages can be easily organized in this repository.
What's included:
turbo.json— Task pipeline configuration forbuild,test,lint,check,fmt, anddevtasks. Root tasks use the//#tasksyntax with scoped inputs for efficient caching. Workspace package builds depend on^buildplus the root SDK build (//#build) to ensure correct ordering.pnpm-workspace.yaml— Workspace package definitions coveringpackages/*,apps/*,confidential-assets,examples/*, andprojects/*.packages/andapps/directories — Scaffolded with.gitkeepfor adding new workspace packages and applications.build:all,test:all,lint:all,check:all,fmt:alladded to rootpackage.json(filtered to core packages only).confidential-assets,examples/*, andprojects/*useworkspace:*protocol for the@aptos-labs/ts-sdkdependency; pnpm overrides consolidated at root; all stale nested lockfiles removed.run-confidential-assets-testsaction now builds the root SDK before running tests (required sinceworkspace:*resolves to the local unbuilt root instead of the pre-built npm package). Playwright browser download skipped in this CI job.INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEEfailures after the defaultmaxGasAmountincrease to 2,000,000..turboadded to.gitignoreAGENTS.md,CLAUDE.md, andCHANGELOG.mdupdated with monorepo structure and new commands.All existing SDK commands (
pnpm build,pnpm test,pnpm check, etc.) continue to work unchanged.Test Plan
pnpm installcorrectly resolves all workspace dependencies (9 workspace projects)turbo run build --dryshows correct dependency ordering (//#build→ dependent packages)pnpm build:allsucceeds: root SDK and confidential-assets build (2 successful, examples/projects excluded via filter)pnpm buildstill works standalone for the SDKpnpm check:allruns biome checks across core workspace packagespnpm checkpasses (242 files, no issues)examples/web-test/node_modules/.bin/after workspace installReview feedback addressed
pnpm-lock.yamlin examples/*, projects/gas-station, andbun.lockin examples/bun-test)@aptos-labs/ts-sdkfromdevDependenciestodependenciesinprojects/gas-stationsince it's imported at runtimepeerDependenciesfromprojects/gas-station(it's a demo app, not a published library)INSUFFICIENT_BALANCE_FOR_TRANSACTION_FEEPLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1to confidential-assets CI install step to avoid unnecessary browser downloads./confidential-assetsfromlint:all/check:all/fmt:allfilters (that package has no lint/check/fmt scripts)console.logstatements from negativeTransfer, negativeWithdraw, and negativeNormalize test files to avoid leaking keys in CI logs; cleaned up unused imports//#buildand//#testetc. — these are correct Turborepo v2 root task definitions;//#buildmaps to the rootpackage.json'sbuildscript, and the//#test///#lint/etc. configure caching inputs when those tasks are run on the root package via{.}filterRelated Links
N/A
Checklist
pnpm fmt?CHANGELOG.md?